package com.medusa.aps.business.modules.modeling.model.input;

import cn.hutool.core.collection.CollUtil;
import com.medusa.aps.business.model.constant.RegexPool;
import com.medusa.aps.business.model.enums.SourceEnum;
import com.medusa.aps.business.modules.modeling.mp.entity.Bom;
import com.medusa.aps.business.common.web.valid.group.Create;
import com.medusa.aps.business.common.web.valid.group.Update;
import com.medusa.aps.business.global.model.o.BaseDTO;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
import lombok.Data;
import lombok.experimental.Accessors;

import java.util.List;

/**
 * @author miskw
 * @date 2023/10/9
 */
@Data
@Accessors(chain = true)
@Schema(description = "bom接收实体")
public class BomDTO implements BaseDTO {
    /**
     * BOM id
     */
    @Schema(description = "BOM id")
    @NotNull(message = "BOM编码不能为空", groups = Update.class)
    public Integer id;
    /**
     * BOM编码
     */
    @Schema(description = "BOM编码")
    @Size(max = 20, message = "BOM编码最长不能超过20个字")
    @Pattern(regexp = RegexPool.ORDER_NO, message = "BOM编码只支持数字、字母、符号")
    @NotNull(message = "BOM编码不能为空", groups = {Create.class, Update.class})
    private String bomCode;

    /**
     * BOM名称
     */
    @Schema(description = "BOM名称")
    @Size(max = 50, message = "BOM名称最长不能超过50个字")
    @NotNull(message = "BOM名称不能为空", groups = {Create.class, Update.class})
    private String bomName;
    /**
     * 物料id
     */
    @Schema(description = "物料id")
    @NotNull(message = "物料id不能为空", groups = {Create.class, Update.class})
    private Long materialId;
    /**
     * 父项物料编码
     */
    @Schema(description = "父项物料编码")
    @NotNull(message = "父项物料编码不能为空", groups = {Create.class, Update.class})
    private String materialCode;
    /**
     * 父项物料名称
     */
    @Schema(description = "父项物料名称")
    @NotNull(message = "父项物料名称不能为空", groups = {Create.class, Update.class})
    private String materialName;
    /**
     * 子项物料
     */
    @Valid
    @Schema(description = "子项物料")
    @NotNull(message = "子项物料不能为空", groups = {Create.class, Update.class})
    @Size(min = 1, max = 10000, message = "第一层子项物料最少不能低于1行，最大不能超过10000行", groups = {Create.class, Update.class})
    private List<BomItemDTO> children;

    public Bom toBom() {
        Bom bom = new Bom();
        bom.setId(id);
        bom.setBomName(getBomName());
        bom.setBomCode(getBomCode());
        bom.setMaterialId(getMaterialId());
        bom.setMaterialCode(getMaterialCode());
        bom.setMaterialName(materialName);
        bom.setDataSource(SourceEnum.ARTIFICIAL);
        return bom;
    }

    /**
     * 限制子项物料总数不超过一万条
     */
    @Override
    public void validParam() {
        if (countChildren(children) > 10000) {
            throw new IllegalArgumentException("物料总数不能超过一万条");
        }
    }

    public int countChildren(List<BomItemDTO> children) {
        int count = 0;
        if (CollUtil.isEmpty(children)) {
            return count;
        }
        count += children.size();
        for (BomItemDTO child : children) {
            count += countChildren(child.getChildren());
        }
        return count;
    }
}
